package com.demo.netty.server;

import com.demo.netty.handler.NettyServerHandler;
import com.demo.netty.protocol.HeatbeatDecode;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.*;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.timeout.IdleStateHandler;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.net.InetSocketAddress;

/**
 * @author liangliang
 */
public class NettyServer {

    private EventLoopGroup boss;
    private EventLoopGroup work;

    @Value("netty.server.port")
    private int port;

    @PostConstruct
    public void start() throws InterruptedException {
        ServerBootstrap sbs = new ServerBootstrap()
            .group(boss, work)
            .channel(NioServerSocketChannel.class)
            .localAddress(new InetSocketAddress(port))
            // 保持长连接
            .childOption(ChannelOption.SO_KEEPALIVE, true)
            .childHandler(new ChannelInitializer<Channel>() {
                @Override
                protected void initChannel(Channel channel) throws Exception {
                    channel.pipeline()
                        // 5秒没有收到消息，将IdleStateHandler添加到 ChannelPipeline 中
                        .addLast(new IdleStateHandler(0, 5, 0))
                        .addLast(new HeatbeatDecode())
                        .addLast(new NettyServerHandler());
                }
            });
        ChannelFuture future = sbs.bind().sync();
        if(future.isSuccess()){
            System.out.println("启动 Netty 成功");
        }
    }

    /**
     * 销毁
     */
    @PreDestroy
    public void destroy(){
        boss.shutdownGracefully().syncUninterruptibly();
        work.shutdownGracefully().syncUninterruptibly();
    }
}
